package com.huaxin.hxmoduleworkorder.listener;

import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderElectricianTaskStatus;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderOperation;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderOperatorRole;
import com.huaxin.hxmoduleworkorder.common.enums.OrderNotificationType;
import com.huaxin.hxmoduleworkorder.dto.request.OrderNotificationCreateReqDTO;
import com.huaxin.hxmoduleworkorder.event.MaintenanceOrderStatusChangedEvent;
import com.huaxin.hxmoduleworkorder.feignclients.SysFeignService;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrder;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrderElectricianTask;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderElectricianTaskService;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderService;
import com.huaxin.hxmoduleworkorder.service.OrderNotificationService;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Component
public class MaintenanceOrderStatusChangeListener {
    private final OrderNotificationService orderNotificationService;
    private final MaintenanceOrderService maintenanceOrderService;
    private final MaintenanceOrderElectricianTaskService electricianTaskService;
    private final SysFeignService sysFeignService;

    public MaintenanceOrderStatusChangeListener(OrderNotificationService orderNotificationService,
                                                MaintenanceOrderService maintenanceOrderService,
                                                MaintenanceOrderElectricianTaskService electricianTaskService,
                                                SysFeignService sysFeignService) {
        this.orderNotificationService = orderNotificationService;
        this.maintenanceOrderService = maintenanceOrderService;
        this.electricianTaskService = electricianTaskService;
        this.sysFeignService = sysFeignService;
    }

    @Async("maintenanceOrderStatusExecutor") // 使用专用线程池
    @EventListener
    @Transactional
    public void handleOrderAssigned(MaintenanceOrderStatusChangedEvent event) {
        MaintenanceOrder order = maintenanceOrderService.getById(event.getOrderId());
        if (order == null) {
            return;
        }
        notifyOrderStatusChange(order, event);
        notifyWhenRollBack(order, event);
    }

    private void notifyOrderStatusChange(MaintenanceOrder order, MaintenanceOrderStatusChangedEvent event) {
        switch (order.getStatus()) {
            case REVIEWING:
                // 通知管理员审核
                createNotification(order, MaintenanceOrderOperatorRole.ADMIN, sysFeignService.getAdminIds(), "工单已提交，请审核！");
                break;
            case ASSIGNED:
            case REASSIGNED:
                // 获取分配的电工ID列表，只通知"assigned"状态的电工
                List<String> electricianIds = electricianTaskService.listByOrderId(order.getId())
                        .stream().filter(electrician -> electrician.getStatus().equals(MaintenanceOrderElectricianTaskStatus.ASSIGNED))
                        .map(MaintenanceOrderElectricianTask::getElectricianId).toList();
                // 通知电工处理
                createNotification(order, MaintenanceOrderOperatorRole.ELECTRICIAN, electricianIds, "工单已分配，请处理！");
                break;
            case RESOLVED:
                // 通知管理员核实
                createNotification(order, MaintenanceOrderOperatorRole.ADMIN, sysFeignService.getAdminIds(), "工单已处理，请审核！");
                break;
            case REJECTED:
                // 通知创建人
                createNotification(order, order.getCreatedByRole(), order.getCreatedBy(), "工单已拒绝，如有需要请重新提交！");
                break;
            default:
                // 其他状态不处理
        }
    }

    /**
     * 回滚时通知
     */
    private void notifyWhenRollBack(MaintenanceOrder order, MaintenanceOrderStatusChangedEvent event) {
        if (!MaintenanceOrderOperation.ROLLBACK.equals(event.getAction())) {
            return;
        }
        switch (order.getStatus()) {
            case CREATED:
                // 通知创建人修改
                createNotification(order, order.getCreatedByRole(), order.getCreatedBy(), "工单已退回，请修改信息后重新提交！");
                break;
            case ASSIGNED:
            case REASSIGNED:
                // 通知管理员、主修电工重新分配
                List<String> recipientIds = sysFeignService.getAdminIds();
                recipientIds.add(order.getElectricianId());
                createNotification(order, MaintenanceOrderOperatorRole.ADMIN, recipientIds, "工单已退回，请重新分配！");
                break;
            default:
                // 其他状态不处理
        }
    }

    private void createNotification(MaintenanceOrder order, MaintenanceOrderOperatorRole recipientRole, String recipientId, String message) {
        createNotification(order, recipientRole, List.of(recipientId), message);
    }

    /**
     * 创建通知
     *
     * @param order         工单信息
     * @param recipientRole 接收者角色
     * @param recipientIds  接收者ID
     * @param message       通知内容
     */
    private void createNotification(MaintenanceOrder order, MaintenanceOrderOperatorRole recipientRole, List<String> recipientIds, String message) {
        if (order == null) {
            return;
        }
        if (recipientRole == null) {
            return;
        }
        if (recipientIds == null || recipientIds.isEmpty()) {
            return;
        }

        for (String recipientId : recipientIds) {
            OrderNotificationCreateReqDTO OrderNotificationCreateReqDTO = new OrderNotificationCreateReqDTO();
            OrderNotificationCreateReqDTO.setOrderType(order.getType().getCode());
            OrderNotificationCreateReqDTO.setOrderId(order.getId());
            OrderNotificationCreateReqDTO.setRecipientId(recipientId);
            OrderNotificationCreateReqDTO.setRecipientRole(recipientRole.getCode());
            OrderNotificationCreateReqDTO.setNotificationType(OrderNotificationType.IN_SYSTEM.getCode());
            OrderNotificationCreateReqDTO.setContent(message);
            orderNotificationService.create(OrderNotificationCreateReqDTO);
        }
    }
}
